﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BuildHelper.Work.GUI;
using ProgNetComponentsDx.Options;

namespace BuildHelper.BHTasks
{
    public class GuiBuildTask : BaseProcesTask
    {
        public GuiBuildTask()
        {
            this.AlertImage = Properties.Resources.burn_gui24;
        }
        [SerializeProperty]
        public string Brancz { get; set; }
        public GuiDataSet DataSet { get; set; }
        [SerializeProperty]
        public string VisualStudio { get; set; }
        [SerializeProperty]
        public string Config { get; set; }
        [SerializeProperty]
        public string Env { get; set; }
        [SerializeProperty]
        public int? Server { get; set; }
        [SerializeProperty]
        public bool Clean { get; set; }
        [SerializeProperty]
        public bool RunApp { get; set; }
        [SerializeProperty]
        public string Template { get; set; }
        
        List<BuildStm> systemy = new List<BuildStm>();
        BuildStm curStm = null;
        string projekt = "";
        int buildProj = 0;
        int buildProjAll = 0;
        int allProjs = 0;
        bool BuildStmError = false;

        private void SetCurStm(BuildStm s)
        {
            if (curStm != s)
            {
                curStm = s;
                buildProj = 0;
                projekt = "";
                BuildStmError = false;
                UpdateTaskInfo();
            }
        }

        protected override bool BeginTask()
        {
            bool res = base.BeginTask();
            if (res)
            {
                systemy.Clear();
                curStm = null;
                projekt = "";
                buildProj = 0;
                buildProjAll = 0;
                allProjs = 0;
                BuildStmError = false;
            }
            return res;
        }

        protected override string GetTaskName()
        {
            string s = "Budowanie gui [" + Brancz + "]";
            //if (Template.IsNotNull())
            //    s += " Template:" + Template;
            return s;
        }

        protected override string GetAlertText()
        {
            string text = "Budowanie Gui [" + Brancz + "]";
            if (systemy != null && curStm != null)
            {
                int cSys = systemy.IndexOf(curStm) + 1;
                int cProj = Math.Max(1, buildProj);
                string p = "";
                if (buildProj > 0)
                    p = projekt;
                text += Constants.NewLineLinux + "System: " + cSys + "/" + systemy.Count + " (" + curStm.System + ")";
                text += Constants.NewLineLinux + "Projekt: " + cProj + "/" + curStm.Projects + " (" + p + ")";
                if (systemy.Count > 1)
                {
                    int ba = Math.Max(buildProjAll, 1);
                    text += Constants.NewLineLinux + "Wszystkie Projekty: " + ba + "/" + allProjs;
                }
            }
            return text;
        }

        protected override void RunTask(System.Diagnostics.Process process)
        {
            if (Template.IsNotNull())
            {
                DataSet = new GuiDataSet();
                BudowanieGuiTools.ReadTemplate(DataSet, Template);
            }
            else if(DataSet == null)
            {
                DataSet = new GuiDataSet();
                string vs, cfg;
                BudowanieGuiTools.ReadBranch(Brancz, DataSet, out vs, out cfg);
            }
            GlobalTools.ProcessTools.SetEnvVariable(process, Brancz);

            systemy.AddRange(BudowanieGuiTools.Buduj(DataSet, VisualStudio, Process, RunApp, Clean, Config, Env, Server));
            allProjs = 0;
            foreach (var i in systemy)
                allProjs += i.Projects;
        }

        protected override string GetMsgForMemo(string msg)
        {
            string t = msg;
            if (msg.XMatch("^" + BudowanieGuiTools.INFO_KONIEC_BUDOWANIA) ||
               msg.XMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA))
                t += " " + DateTime.Now.ToString("G");
            
            if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Work_Group.Gui.AddTimeToLog))
                t = DateTime.Now.ToString("G") + "    " + t;

            if (msg.XMatch("Build started") || msg.XMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA))
                t = "\n\n" + t;
            if (msg.XMatch("devenv"))
                t = "\n\n" + t;
            if (msg.XMatch("Project \"(.*\\.sln)\" is building"))
                t = "\n\n" + t;

            return t;
        }
        
        protected override bool ShouldAddMsgToMemo(string msg)
        {
            if (msg.XMatch("^" + BudowanieGuiTools.INFO_KONIEC_BUDOWANIA) ||
               msg.XMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA))
                return true;

            return BudowanieGuiTools.ShouldAddLog(msg);
        }

        protected override void ProcessMessage(string str)
        {
            if (str.XMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA))
            {
                if (systemy != null)
                {
                    string stm = str.GetFirstMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA + " (\\w*)");
                    if (stm != null)
                    {
                        foreach (BuildStm s in systemy)
                        {
                            if (s.System.ToLower() == stm.ToLower())
                            {
                                SetCurStm(s);
                                break;
                            }
                        }
                    }
                }
            }

            if (str.XMatch("^" + BudowanieGuiTools.INFO_URUCHOM))
            {
                if (!BuildStmError)
                {
                    string m = "(.*)".AddDoubleQuotes();
                    string mask = m + " " + m + " " + m + " " + m;
                    string exe = str.GetFirstMatch(mask, 1);
                    string sln = str.GetFirstMatch(mask, 2);
                    string env = str.GetFirstMatch(mask, 3);
                    string server = str.GetFirstMatch(mask, 4);
                    int? srv = null;
                    if (server.IsNotNull())
                        srv = server.AsInt();
                    try
                    {
                        BudowanieGuiTools.ReplaceUrl(exe, sln, env, srv);
                        GlobalTools.FilesTools.RunFile(exe, "exe");
                        if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Work_Group.Gui.UpdateConfigOnlyForRun))
                        {
                            System.Threading.Thread.Sleep(50);
                            BudowanieGuiTools.ReplaceUrl(exe, sln, "", null);
                        }
                    }
                    catch (Exception ex)
                    {
                        ex.Log();
                        FormMain.ShowErrorAlert("Błąd uruchamiania " + curStm.System);
                    }
                }
                else
                {
                    FormMain.ShowWarningAlert(curStm.System + " nie zostanie uruchomiony ze względu na błędy w budowaniu.");
                }
                return;
            }
            string csprojMask1 = "Build started:\\sProject:\\s(\\w*)";
            string csprojMask2 = "Done building target \"BeforeBuild\" in project \"(.*?)\\.csproj\"";
            projekt = str.GetFirstMatch(csprojMask1);
            if (projekt.IsNull())
                projekt = str.GetFirstMatch(csprojMask2);
            
            if (projekt.IsNotNull())
            {
                buildProjAll++;
                buildProj++;
                UpdateTaskInfo();
            }
        }

        protected override bool IsError(string msg)
        {
            return BudowanieGuiTools.FindError(msg);
        }
        
    }
}
